//
// Created by 刘禹晨 on 5/18/16.
// Copyright (c) 2016 刘禹晨. All rights reserved.
//

#import "BLEManager.h"
#import <CoreBluetooth/CoreBluetooth.h>
#import "Mode.h"

@interface BLEManager()  <CBCentralManagerDelegate,CBPeripheralDelegate>

{
    BOOL inited;
    CBCentralManager *manager;
    NSInteger connectState;
    NSInteger readState;
    NSMutableDictionary *detailDic;
    NSTimer *timer;
    NSNumberFormatter* numberFormatter;
    Mode *_mode;
}


@end

@implementation BLEManager

+ (BLEManager *)instance {
    static BLEManager *_instance = nil;

    @synchronized (self) {
        if (_instance == nil) {
            _instance = [[self alloc] init];
        }
    }

    return _instance;
}

-(void)setup
{
    if (inited) {
        return;
    }
    inited = TRUE;
    numberFormatter = [[NSNumberFormatter alloc] init];
    self.delegate = nil;
    self.dicoveredPeripherals = [NSMutableArray array];
    self.recvMsgData = [NSMutableData data];
    self.services = [NSMutableArray array];
    detailDic = [NSMutableDictionary dictionary];
    self.currentPeripheral = nil;
    connectState = KNOT;
    _mode = [Mode instance];
    //NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:false],CBCentralManagerScanOptionAllowDuplicatesKey, nil];
    manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    NSLog(@"init bt server ........");
}

-(void)BLEDisconnect{
    if(self.currentPeripheral != nil)
    {
        [manager cancelPeripheralConnection:self.currentPeripheral];
    }else{
        if(manager.isScanning == YES)
        {
            [manager stopScan];
        }
        [detailDic setObject:@" " forKey:@"RSSI"];
        [detailDic setObject:@"未连接" forKey:@"state"];
        [detailDic setObject:@" " forKey:@"name"];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"leftMenuDataSet" object:nil userInfo:detailDic];
        NSLog(@"无设备连接");
    }
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{

    NSLog(@"centeralManger: ");

    if(![self.dicoveredPeripherals containsObject:peripheral]){
        [self.dicoveredPeripherals addObject:peripheral];
    }
    
    
    for(CBPeripheral *obj in self.dicoveredPeripherals)
    {
        if([obj.name isEqual: @"<SHUNLAN1>"])
        {
            [self connect:obj];
            break;
        }
    }
    NSLog(@"dicoveredPeripherals:%@", self.dicoveredPeripherals);

    if(self.delegate && [(id)self.delegate respondsToSelector:@selector(didFoundPeripheral)])
    {
        [self.delegate didFoundPeripheral];
    }
}

-(void) centralManagerDidUpdateState:(CBCentralManager *)central
{
    switch (central.state){
        case CBCentralManagerStatePoweredOn:
            NSLog(@"蓝牙已打开,请扫描外设");
            if([_mode.mode isEqualToString:@"BLE"]){
                [self scan];//扫描
            }
            break;
        case CBCentralManagerStateUnsupported:
            NSLog(@"您的设备不支持蓝牙或蓝牙4.0");
            break;
        case CBCentralManagerStateUnauthorized:
            NSLog(@"未授权");
            break;
        case CBCentralManagerStatePoweredOff://蓝牙未打开，系统会自动提示打开，所以不用自行提示
        default:
            break;
    }
}

-(BOOL)connect:(CBPeripheral*)peripheral{

    NSLog(@"connect start");
    self.currentPeripheral = nil;
    if([peripheral.name  isEqual: BLENAME] )
        [manager connectPeripheral:peripheral options:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
    return YES;
}

-(void)scan{
    NSLog(@"开始扫描");
    if(manager.state == CBCentralManagerStatePoweredOn){
            [manager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey :@NO}];
        [detailDic setObject:@" " forKey:@"RSSI"];
        [detailDic setObject:@" " forKey:@"name"];
        [detailDic setObject:@"正在扫描..." forKey:@"state"];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"leftMenuDataSet" object:nil userInfo:detailDic];
    }else{
        [detailDic setObject:@" " forKey:@"RSSI"];
        [detailDic setObject:@" " forKey:@"name"];
        [detailDic setObject:@"蓝牙未打开" forKey:@"state"];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"leftMenuDataSet" object:nil userInfo:detailDic];
    }
}

- (void)centralManager:(CBCentralManager*)central didConnectPeripheral:(CBPeripheral*)peripheral
{
    //[connectTimerinvalidate];//停止时钟
    NSLog(@"Did connect toperipheral: %@", peripheral);

    self.currentPeripheral = peripheral;

    [manager stopScan];

    [peripheral setDelegate:self];
    [detailDic setObject:@"已连接" forKey:@"state"];
    [detailDic setObject:peripheral.name forKey:@"name"];
    [peripheral discoverServices:nil];//发现服务
    
    if (!timer) {
        timer = [NSTimer scheduledTimerWithTimeInterval:2.0
                                            target:self
                                            selector:@selector(readPeripheralRSSI)
                                            userInfo:nil
                                            repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    }
    //[peripheral readRSSI];
    
    self.currentPeripheral.delegate = self;

    if(self.delegate && [(id)self.delegate respondsToSelector:@selector(didConnected)])
    {
        [self.delegate didConnected];
    }

}

-(void)readPeripheralRSSI
{
    //NSLog(@"Timer......");
    [self.currentPeripheral readRSSI];
}

//连接外设失败

-(void)centralManager:(CBCentralManager*)central didFailToConnectPeripheral:(CBPeripheral*)peripheral error:(NSError *)error
{

    NSLog(@"%@",error);
    [self scan];

}

//已发现服务
-(void) peripheral:(CBPeripheral*)peripheral didDiscoverServices:(NSError*)error{
    for (CBService *s in peripheral.services){
        [self.services addObject:s];
    }
    for (CBService *s in peripheral.services){
        //NSLog(@"服务 UUID: %@(%@)",s.UUID.data,s.UUID);
        [peripheral discoverCharacteristics:nil forService:s];
    }
}

//已搜索到Characteristics
-(void) peripheral:(CBPeripheral*)peripheral didDiscoverCharacteristicsForService:(CBService*)service error:(NSError *)error{
    NSLog(@"发现特征的服务:%@ (%@)",service.UUID.data ,service.UUID);
    for (CBCharacteristic *c in service.characteristics) {
        NSLog(@"特征UUID: %@ (%@)",c.UUID.data,c.UUID);
        if ([c.UUID isEqual:[CBUUID UUIDWithString:@"FFE1"]]) {//读取
            [peripheral setNotifyValue:YES forCharacteristic:c];
        }
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if (error){
        //readState = KFAILED;
        NSLog(@"Error updating value for characteristic %@ error: %@", characteristic.UUID, [error localizedDescription]);
        return;
    }
    readState = KSUCCESS;
    self.cbCharacteristic = characteristic;
    if([(id)self.delegate respondsToSelector:@selector(didReadvalue)])
    {
        [self.delegate didReadvalue];
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didReadRSSI:(NSNumber *)RSSI error:(NSError *)error
{
//    int iRssi = abs([RSSI intValue]);
//    float power = (iRssi-59)/(10*2.0);
//    NSLog(@"%f m",pow(10, power));
    numberFormatter = [[NSNumberFormatter alloc] init];
    NSString *RSSIString = [numberFormatter stringFromNumber:RSSI];
    [detailDic setObject:[RSSIString stringByAppendingString:@" dbm"] forKey:@"RSSI"];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"leftMenuDataSet" object:nil userInfo:detailDic];
}

-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    [timer invalidate];
    timer = nil;
    [detailDic setObject:@" " forKey:@"RSSI"];
    [detailDic setObject:@"未连接" forKey:@"state"];
    [detailDic setObject:@" " forKey:@"name"];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"leftMenuDataSet" object:nil userInfo:detailDic];
    NSLog(@"disConnect, %@",error);
    if(error != nil)
    {
        [self scan];
    }
}





@end